package vip.xiaomaoxiaoke.util;

import lombok.Data;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * 本地单例缓存，适合缓存一些第三方的token等等消息
 * @author zhuohanjie
 * */
@Data
public class LocalSingletonCache<T> {

    /**
     * 缓存值
     * */
    private T value;

    /**
     * 上次更新时间戳，单位毫秒
     * */
    private long lastUpdateTime;


    /**
     * 过期时间,单位毫秒
     * */
    private final long expirationTime;

    /**
     * 获取缓存值的函数式接口
     * */
    private Supplier<T> supplier;

    private void  init() {
        this.lastUpdateTime = 0L;
    }


    public LocalSingletonCache(Supplier<T> supplier){
        if (supplier == null) {
            throw new IllegalArgumentException();
        }
        init();
        this.supplier = supplier;
        // 默认过期时间一小时
        this.expirationTime = 1000L * 60L * 60L;
    }


    public LocalSingletonCache(Supplier<T> supplier,long expirationTime){
        if (supplier == null || expirationTime <= 0L) {
            throw new IllegalArgumentException();
        }
        init();
        this.supplier = supplier;
        this.expirationTime = expirationTime;

    }


    public LocalSingletonCache(Supplier<T> supplier, long expirationTime, TimeUnit unit){
        if (supplier == null || expirationTime <= 0L) {
            throw new IllegalArgumentException();
        }
        init();
        this.supplier = supplier;
        this.expirationTime =  unit.toMillis(expirationTime);
    }



    /**
     * 获取缓存值
     * */
    public T get() {
        // 获取当前时间戳
        long currentTimeMillis = System.currentTimeMillis();

        // 判断缓存值是否初始化或者判断缓存值是否过期
        if (this.lastUpdateTime == 0L || currentTimeMillis - this.lastUpdateTime > this.expirationTime) {
            this.value = supplier.get();
            this.lastUpdateTime = currentTimeMillis;
        }
        // 返回缓存值
        return this.value;
    }



}
